package cn.tqfeiyang.springplus.framework.configuration;

import cn.tqfeiyang.springplus.framework.Constants;
import cn.tqfeiyang.springplus.framework.security.JwtSecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import org.springdoc.core.customizers.OperationCustomizer;
import org.springframework.web.method.HandlerMethod;

@Configuration
public class SwaggerConfiguration {

    @Bean
    public OpenAPI swaggerOpenAPI() {
        Info info = new Info().title("系统接口文档")
                .version("v2.7.18");

        SecurityScheme securityScheme = new SecurityScheme()
                .type(SecurityScheme.Type.HTTP)
                .scheme("bearer")
                .bearerFormat("JWT")
                .in(SecurityScheme.In.HEADER)
                .name("jwt");

        Components components = new Components()
                //.addSecuritySchemes("bearer-jwt", securityScheme);
                .addSecuritySchemes(Constants.AUTH_TOKEN_HEADER, securityScheme);

        return new OpenAPI()
                .info(info)
                .components(components);
    }

    @Bean
    public GroupedOpenApi allApi() {
        return GroupedOpenApi.builder()
                .group("default")
                .pathsToExclude("/api/auth/**", "/api/echo/**")
                .addOperationCustomizer(customize)
                .build();
    }

    @Bean
    public GroupedOpenApi publicApi() {
        return GroupedOpenApi.builder()
                .group("public")
                .pathsToMatch("/api/auth/**", "/api/echo/**")
                .addOperationCustomizer(customize)
                .build();
    }

    private OperationCustomizer customize = new OperationCustomizer() {
        @Override
        public Operation customize(Operation operation, HandlerMethod handlerMethod) {
            if (handlerMethod.hasMethodAnnotation(JwtSecurityRequirement.class) ||
                    handlerMethod.getBeanType().isAnnotationPresent(JwtSecurityRequirement.class)) {
                operation.addSecurityItem(new SecurityRequirement().addList(Constants.AUTH_TOKEN_HEADER));
            }
            return operation;
        }
    };
}
